package com.gilight.base.controller;

import com.alibaba.fastjson.JSONObject;
import com.gilight.base.admin.brand.AdminBrandService;
import com.gilight.base.base.RepStatusCode;
import com.gilight.base.base.ResultEntity;
import com.gilight.base.base.exception.ServiceException;
import com.gilight.base.dto.CodeGeneratorDto;
import com.gilight.base.dto.uni.UserDTO;
import com.gilight.base.model.BrandDo;
import com.gilight.base.properties.UnimallWxAppProperties;
import com.gilight.base.service.CodeGeneratorService;
import com.gilight.base.service.UserService;
import com.gilight.base.util.RetrofitUtil;
import com.gilight.base.util.SHAUtil;
import com.gilight.base.util.SessionUtil;
import com.gilight.base.util.WechatUtils;
import com.gilight.base.wechart.http.INoty;
import com.gilight.base.wechart.http.IPersonal;
import com.gilight.base.wechart.model.CodeSession;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.codec.Base64;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.checkerframework.checker.units.qual.A;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;
import retrofit2.Retrofit;
import retrofit2.http.Query;

import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.security.AlgorithmParameters;
import java.security.Security;
import java.util.*;
import java.util.stream.Collectors;

@RestController
@RequestMapping("/wx/lite")
public class WeChartController {
    @Autowired
    private CodeGeneratorService codeGeneratorService;
    @Autowired
    private UserService userService;
    @Autowired
    private AdminBrandService adminBrandService;
    @RequestMapping(value = "/n/code-session", method = {RequestMethod.GET})
    public ResultEntity<Map<String,Object>> generate(String appid
            , String secret
            , String js_code
            , @RequestParam(defaultValue = "authorization_code",required = false) String grant_type) {
        Retrofit retrofit = RetrofitUtil.WxLiteBuile();
        IPersonal personal = retrofit.create(IPersonal.class);
        ResultEntity resultEntity = new ResultEntity();
        try {

            Call<CodeSession> responseCallCodeSession = personal.getCodeSession(appid,secret,js_code,grant_type);

            CodeSession codeSession = responseCallCodeSession.execute().body();
            Integer code = codeSession.getErrcode()==null?200:codeSession.getErrcode();
            if(code == 200){
                codeSession.setErrcode(200);
            }
            resultEntity.setStatus(code);
            resultEntity.setData(codeSession);
        } catch (IOException e) {
            e.printStackTrace();
        }
        return resultEntity;
    }

    /**
     *
     * @param loginType  登陆方式 非必填  可以不填有默认值
     * @param ip         当前登陆IP
     * @param raw        {"code":"xxxxxxxx"}
     * @return
     */
    @RequestMapping(value = "/n/login", method = {RequestMethod.GET})
    public ResultEntity<UserDTO> weChartLogin(
              @RequestParam(required = false,defaultValue = "1") Integer loginType
            ,  @RequestParam(required = false,defaultValue = "1") Long brandType
            , String ip
            , String raw
            ) {
        ResultEntity resultEntity = ResultEntity.success();
        try {
            UserDTO userDto = userService.thirdPartLogin(loginType,brandType,ip,raw);
            SessionUtil.setUser(userDto);
            resultEntity.setData(userDto);
        } catch (ServiceException e) {
            e.printStackTrace();
        }
        return resultEntity;
    }
    @Autowired
    private UnimallWxAppProperties unimallWxAppProperties;
    @RequestMapping(value = "/n/code-get-phonenum", method = {RequestMethod.GET})
    public ResultEntity<Map<String,Object>> getPhone(String appid
                                                     , String secret
                                                     , String js_code
                                                     ,String ivObj
                                                     ,String telObj
                                                     ,Long brandType
                                                     , @RequestParam(defaultValue = "authorization_code",required = false) String grant_type) {
        Retrofit retrofit = RetrofitUtil.WxLiteBuile();
        IPersonal personal = retrofit.create(IPersonal.class);
        ResultEntity resultEntity = new ResultEntity();
        try {
            BrandDo brandDo = adminBrandService.getById(brandType);
            if(brandDo!=null&& StringUtils.isNotEmpty(brandDo.getMiniAppId())&&StringUtils.isNotEmpty(brandDo.getMiniAppSec())){
                appid = brandDo.getMiniAppId();
                secret = brandDo.getMiniAppSec();
            }else{
                appid = this.unimallWxAppProperties.getMiniAppId();
                secret= this.unimallWxAppProperties.getMiniAppSecret();
            }
            Call<CodeSession> responseCallCodeSession = personal.getCodeSession(appid,secret,js_code,grant_type);

            CodeSession codeSession = responseCallCodeSession.execute().body();
            Integer code = codeSession.getErrcode()==null?200:codeSession.getErrcode();
            if(code == 200){
                codeSession.setErrcode(200);
            }
            resultEntity.setStatus(code);
            String wxDecrypt = WechatUtils.wxDecrypt(telObj, codeSession.getSession_key(), ivObj);
            resultEntity.setData(wxDecrypt);
        } catch (IOException e) {
            e.printStackTrace();
        }
        return resultEntity;
    }


    public static void main(String [] args){
//        new WeChartController().generate("a","a","a","a");
        Retrofit retrofit = RetrofitUtil.NotyBuile();
        INoty iNoty = retrofit.create(INoty.class);
        String appid = "c19900804";
        String gp = "developer";
        String mt = "getRegisterUrl";
        String appSc = "asdfasdfasdfas";
        Date d = new Date();
        Long timestamp = d.getTime();
        String userId = "asdftest";

        List<String> sginList = new ArrayList<>();
        sginList.add(appid);
        sginList.add(gp);
        sginList.add(mt);
        sginList.add(String.valueOf(timestamp));
        sginList.add(appSc);
        sginList.add(userId);
        String sgin = "";
        String raw = sginList.stream().map(item -> {
            //签名本身无法加入签名算法参数中, 而appSecret 需要加入签名中。所以遇到签名时，将其替换为appSecert即可
            return item;
        }).sorted().collect(Collectors.joining());
        try {
            sgin = SHAUtil.shaEncode(URLEncoder.encode(raw, "utf-8"));
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }


        Call<HashMap> responseCallCodeSession = iNoty.getRegisterUrl(appid,gp,mt,timestamp,sgin,userId);
        try {
            HashMap a = responseCallCodeSession.execute().body();
            System.out.println(a.toString());
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
